
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>6、JUC异步编程 - 学习卡片</title>
      <style>
        body { font-family: sans-serif; background-color: #f0f8ff; color: #333; display: flex; flex-direction: column; align-items: center; padding: 50px 20px; }
        .header h1 { font-size: 32px; }
        .grid-container { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; width: 100%; max-width: 1200px; }
        .card-container { perspective: 1200px; cursor: pointer; height: 250px; }
        .card { width: 100%; height: 100%; position: relative; transform-style: preserve-3d; transition: transform 0.7s; border-radius: 16px; box-shadow: 0 4px 16px rgba(0,0,0,0.08); }
        .card-container.flipped .card { transform: rotateY(180deg); }
        .card-face { position: absolute; width: 100%; height: 100%; backface-visibility: hidden; display: flex; flex-direction: column; box-sizing: border-box; border-radius: 16px; background-color: #fff; padding: 24px; }
        .card-back { background-color: #f0fff4; transform: rotateY(180deg); justify-content: space-between; }
        .card-category { font-size: 14px; color: #0052d9; margin-bottom: 8px; font-weight: 500; }
        .card-question { font-size: 20px; font-weight: 500; flex-grow: 1; display: flex; align-items: center; justify-content: center; text-align: center; }
        .card-answer-wrapper { flex-grow: 1; overflow-y: auto; }
        .card-answer { font-size: 15px; line-height: 1.7; }
        .card-footer { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 16px; margin-top: 16px; }
        .card-source { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 12px; margin-top: 12px; }
      </style>
    </head>
    <body>
      <div class="header">
        <h1>6、JUC异步编程 - 学习卡片</h1>
      </div>
      <div class="grid-container">
        
    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">理论</div>
          <div class="card-question">JUC的全称是什么？它被设计用来解决什么核心问题？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">理论</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">JUC是java.util.concurrent包的简称，意为Java并发编程工具包。其目的在于更好地支持高并发任务，并帮助开发者在进行多线程开发时，有效减少竞争条件和死锁线程的发生。</div>
          </div>
          <div class="card-source">来源: 什么是JUC</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">特性</div>
          <div class="card-question">在CompletableFuture中，`runAsync`方法和`supplyAsync`方法在功能上的主要区别是什么？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">特性</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">`runAsync`方法用于执行没有返回值的异步任务，而`supplyAsync`方法用于执行有返回值的异步任务。</div>
          </div>
          <div class="card-source">来源: CompletableFuture - runAsync 和 supplyAsync方法</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">当使用CompletableFuture的`whenComplete`和`whenCompleteAsync`进行回调时，它们的线程执行机制有何不同？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">主要区别在于执行回调任务的线程不同：`whenComplete`是由执行当前任务的线程继续执行回调任务；而`whenCompleteAsync`是把回调任务作为一个新任务提交给线程池来执行。</div>
          </div>
          <div class="card-source">来源: CompletableFuture - 计算结果完成时的回调方法</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">特性</div>
          <div class="card-question">当需要组合多个CompletableFuture任务时，`allOf`和`anyOf`方法的使用场景和行为有何区别？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">特性</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">`allOf`用于等待所有指定的任务都执行完成后才返回，适用于需要所有子任务结果的场景。而`anyOf`只要其中任意一个任务执行完成就会返回，适用于只要获得最快结果的场景。</div>
          </div>
          <div class="card-source">来源: CompletableFuture - 多任务组合</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">Spring框架中的`@Scheduled`注解在默认情况下存在什么潜在问题？文档中提到了哪两种解决方案？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">默认情况下，`@Scheduled`任务是单线程执行的，如果某个任务耗时过长，会阻塞后续任务的执行。文档提到的解决方案有两种：1. 使用`@Async`注解开启异步处理；2. 在任务方法内部使用自定义的线程池来处理耗时逻辑。</div>
          </div>
          <div class="card-source">来源: Java定时调度机制 - @Scheduled单线的问题</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">模式</div>
          <div class="card-question">在高并发系统中实施“请求合并”模式的主要目的是什么？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">模式</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">请求合并的主要目的有两个：一是减少对数据库的访问次数；二是在单位时间内将多个独立的请求合并成一个批量请求，从而可以利用批量查询SQL或Redis的pipeline等技术提高性能。</div>
          </div>
          <div class="card-source">来源: 请求合并 - 场景</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">理论</div>
          <div class="card-question">Fork/Join框架的核心设计思想是什么？它主要通过哪两个步骤来提升性能？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">理论</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">Fork/Join框架的核心思想是将一个大任务分割成若干个小任务，并行执行这些小任务，最后将它们的结果汇总以得到大任务的结果。它主要通过两个步骤实现：1. 任务分割（Fork）；2. 执行任务并合并结果（Join）。</div>
          </div>
          <div class="card-source">来源: Fork/Join框架</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">Fork/Join框架依赖哪两个核心类来运作？它们各自扮演什么角色？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">该框架依赖于`ForkJoinTask`和`ForkJoinPool`两个核心类。`ForkJoinTask`是任务的抽象，我们需要继承它（通常是其子类RecursiveTask）来定义任务的分割和计算逻辑。`ForkJoinPool`则负责执行`ForkJoinTask`任务。</div>
          </div>
          <div class="card-source">来源: Fork/Join框架</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">Fork/Join框架中的“工作窃取算法”是如何运作的？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">在Fork/Join框架中，每个工作线程维护一个双端队列。当一个工作线程完成了自己队列中的所有任务后，它会随机地从其他工作线程的队列的尾部“窃取”一个任务来执行，以提高线程利用率和整体性能。</div>
          </div>
          <div class="card-source">来源: Fork/Join框架</div>
        </div>
      </div>
    </div>

      </div>
    </body>
    </html>
